﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Vizzio.Models;
using Vizzio.DAL;
using System.Globalization;

namespace Vizzio.Controllers
{
    public class IngresoDeProductoController : Controller
    {
        private VizzioContext db = new VizzioContext();

        // GET: /IngresoDeProducto/
        public ActionResult Index()
        {
            IEnumerable<IngresoDeProducto> ingresoDeProducto = db.IngresoDeProductos.ToList();
            ingresoDeProducto = ingresoDeProducto.Where(i => i.Eliminado == false);
            return View(ingresoDeProducto);
        }

        public ActionResult Buscar(string FechaInicial, string FechaFinal)
        {
            IEnumerable<IngresoDeProducto> ingresoDeProductos = db.IngresoDeProductos.ToList();
            IFormatProvider provider = CultureInfo.CreateSpecificCulture("es-ES");
            if (!string.IsNullOrEmpty(FechaInicial))
            {
                if (!string.IsNullOrEmpty(FechaFinal))
                {
                    ingresoDeProductos = ingresoDeProductos.Where(ingresoDeProducto => ingresoDeProducto.Fecha >= DateTime.Parse(FechaInicial, provider) && ingresoDeProducto.Fecha <= DateTime.Parse(FechaFinal, provider) && ingresoDeProducto.Eliminado == false);
                }
                else
                {
                    ingresoDeProductos = ingresoDeProductos.Where(ingresoDeProducto => ingresoDeProducto.Fecha >= DateTime.Parse(FechaInicial, provider) && ingresoDeProducto.Eliminado == false);
                }
                
            }
            else if (!string.IsNullOrEmpty(FechaFinal))
            {
                ingresoDeProductos = ingresoDeProductos.Where(ingresoDeProducto => ingresoDeProducto.Fecha <= DateTime.Parse(FechaFinal, provider) && ingresoDeProducto.Eliminado == false);
            }
            
            return View("Index", ingresoDeProductos.ToList());
        }

        // GET: /IngresoDeProducto/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            IngresoDeProducto ingresoDeProducto = db.IngresoDeProductos.Find(id);
            if (ingresoDeProducto == null)
            {
                return HttpNotFound();
            }
            return View(ingresoDeProducto);
        }

        // GET: /IngresoDeProducto/Create
        public ActionResult Create()
        {
            string codigo = DateTime.Today.Year.ToString();
            int dia = DateTime.Today.Day;
            int mes = DateTime.Today.Month;
            if (mes < 10)
            {
                codigo = codigo + "0" + mes.ToString();
            }
            else
            {
                codigo = codigo + mes.ToString();
            }
            if (dia < 10)
            {
                codigo = codigo + "0" + dia.ToString();
            }
            else
            {
                codigo = codigo + dia.ToString();
            }
            string aux = "I-" + codigo;
            string aux2 = "II-" + codigo;
            int ingresoDeProductos = db.IngresoDeProductos.Where(ingresoDeProducto => ingresoDeProducto.CodigoDeIngresoDeProducto.Contains(aux) && !ingresoDeProducto.CodigoDeIngresoDeProducto.Contains(aux2) && ingresoDeProducto.Eliminado == false).ToList().Count();
            if (ingresoDeProductos > 0)
            {
                ingresoDeProductos = db.IngresoDeProductos.Where(ingresoDeProducto => ingresoDeProducto.CodigoDeIngresoDeProducto.Contains(aux)).ToList().Count();
                TempData["Informacion"] = "Atencion! Ya se registraron una o mas Importaciones el dia de hoy!!";
            }

            var productos = (from s in db.Productoes
                         join pp in db.Presentaciones on s.PresentacionID equals pp.PresentacionID
                         select new
                         {
                             NombreCompleto = s.Nombre + " " + pp.NombrePresentacion,
                             ProductoID = s.ProductoID
                         }).ToList();

            var socios = (from socio in db.Socios
                         select new
                         {
                             NombreCompleto = socio.Nombre + " " + socio.Apellidos,
                             SocioID = socio.SocioID
                         }).ToList();

            ViewBag.ListaDeProductos = new SelectList(productos, "ProductoID", "NombreCompleto", null);

            ViewBag.ListaDeSocios = new SelectList(socios, "SocioID", "NombreCompleto", null);

            ViewBag.CodigoDeIngresoDeProducto = codigo + "-" + ingresoDeProductos;
            return View();
        }

        // POST: /IngresoDeProducto/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(IngresoDeProducto ingresoDeProducto, ICollection<ProductoEsperado> ProductoEsperado, ICollection<ProductoDeSocio> ProductoDeSocio)
        {
            ViewBag.CodigoDeIngresoDeProducto = ingresoDeProducto.CodigoDeIngresoDeProducto;

            string codigo = DateTime.Today.Year.ToString();
            int dia = DateTime.Today.Day;
            int mes = DateTime.Today.Month;
            if (mes < 10)
            {
                codigo = codigo + "0" + mes.ToString();
            }
            else
            {
                codigo = codigo + mes.ToString();
            }
            if (dia < 10)
            {
                codigo = codigo + "0" + dia.ToString();
            }
            else
            {
                codigo = codigo + dia.ToString();
            }
            string aux3 = "I-" + codigo;
            string aux2 = "II-" + codigo;
            int ingresoDeProductos = db.IngresoDeProductos.Where(ingresoProd => ingresoProd.CodigoDeIngresoDeProducto.Contains(aux3) && !ingresoProd.CodigoDeIngresoDeProducto.Contains(aux2) && ingresoProd.Eliminado == false).ToList().Count();
            if (ingresoDeProductos > 0)
            {
                ingresoDeProductos = db.IngresoDeProductos.Where(ingresoProd => ingresoProd.CodigoDeIngresoDeProducto.Contains(aux3)).ToList().Count();
                TempData["Informacion"] = "Atencion! Ya se registraron una o mas Importaciones el dia de hoy!!";
            }
            var productos = (from s in db.Productoes
                             join pp in db.Presentaciones on s.PresentacionID equals pp.PresentacionID
                             select new
                             {
                                 NombreCompleto = s.Nombre + " " + pp.NombrePresentacion,
                                 ProductoID = s.ProductoID
                             }).ToList();
            var socios = (from socio in db.Socios
                          select new
                          {
                              NombreCompleto = socio.Nombre + " " + socio.Apellidos,
                              SocioID = socio.SocioID
                          }).ToList();

            ViewBag.ListaDeProductos = new SelectList(productos, "ProductoID", "NombreCompleto", null);
            ViewBag.ListaDeSocios = new SelectList(socios, "SocioID", "NombreCompleto", null);
            ViewBag.CodigoDeIngresoDeProducto = codigo + "-" + ingresoDeProductos;

            if(ProductoEsperado!=null && ProductoEsperado.Where(prod => prod.Eliminar == 0).ToList().Count()>0)
            {
                ingresoDeProducto.Eliminado = false;
                ingresoDeProducto.ProductosEsperados = null;
                try
                {
                    float total = 0;
                    db.IngresoDeProductos.Add(ingresoDeProducto);
                    db.SaveChanges();
                    foreach (ProductoEsperado prod in ProductoEsperado)
                    {
                        prod.ProductosDeSocio = null;
                        if (prod.Eliminar == 0)
                        {
                            total = total + (float)(prod.CantidadEsperada * prod.PrecioUnitarioDeCompra);
                            prod.IngresoDeProducto = ingresoDeProducto;
                            if (ingresoDeProducto.Concepto == "InventarioInicial")
                            {
                                prod.CantidadRecibida = prod.CantidadEsperada;
                                Producto aux = db.Productoes.Find(prod.ProductoID);
                                aux.Precio = prod.PrecioUnitarioDeCompra;
                                aux.Stock = aux.Stock+prod.CantidadEsperada;
                                db.Entry(aux).State = EntityState.Modified;
                                db.SaveChanges();
                            }
                            db.ProductosEsperados.Add(prod);
                            db.SaveChanges();
                            foreach (ProductoDeSocio prodDeSocio in ProductoDeSocio)
                            {
                                if (prodDeSocio.Eliminar == 0 && prodDeSocio.ProductoID==prod.ProductoID)
                                {
                                    prodDeSocio.ProductoEsperadoID = prod.ProductoEsperadoID;
                                    //Quitar esto
                                    prodDeSocio.CantidadActual = prodDeSocio.CantidadEsperada;
                                    db.ProductosDeSocio.Add(prodDeSocio);
                                    db.SaveChanges();
                        }
                    }
                    
                        }
                    }
                    
                    //db.SaveChanges();
                    if (ingresoDeProducto.Concepto == "InventarioInicial")
                    {
                        ingresoDeProducto.FechaRecibida = DateTime.Now.Date;
                    }
                    ingresoDeProducto.CostoTotal = total;
                    ingresoDeProducto.EstadoIngresoProducto = "Creado";
                    db.Entry(ingresoDeProducto).State = EntityState.Modified;
                    db.SaveChanges();
                    TempData["Correcto"] = "Se registro el ingreso de los productos!";
                    return RedirectToAction("Index");
                    //return RedirectToAction("AsignarProductosASocio",new {@id=ingresoDeProducto.IngresoDeProductoID});
                }
                catch
                {
                    TempData["Error"] = "Ocurrio algun problema al realizar la operacion!";
                    return View(ingresoDeProducto);
                }
            }
            TempData["Error"] = "Debe agregar almenos un producto.";
            return View(ingresoDeProducto);
           
        }

        public ActionResult AsignarProductosASocio(int? id)
        {
            IngresoDeProducto ingresoDeProducto = db.IngresoDeProductos.Find(id);
            TempData["Socios"] = db.Socios.Where(socio => socio.Eliminado == false).ToList();
            return View(ingresoDeProducto);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult AsignarProductosASocio(List<ProductoDeSocio> ProductosDeSocio, List<AporteSocio> AporteSocio)
        {
            //int productoEsperadoID = -1;
            //IngresoDeProducto ingresoDeProducto=null;
            //if (ModelState.IsValid)
            //{
            //    foreach (ProductoDeSocio p in ProductosDeSocio)
            //    {
            //        if (p.SocioID > 0)
            //        {
            //            db.ProductosDeSocio.Add(p);
            //            productoEsperadoID = p.ProductoEsperadoID;
            //        }
            //    }
            //    if (productoEsperadoID != -1)
            //    {
            //        ProductoEsperado prod = db.ProductosEsperados.Find(productoEsperadoID);
            //        ingresoDeProducto=prod.IngresoDeProducto;
            //        ingresoDeProducto.EstadoIngresoProducto="Repartido";
            //        db.Entry(ingresoDeProducto).State=EntityState.Modified;
                    
            //     }
            //    db.SaveChanges();
                
            //}
            //if (ingresoDeProducto != null)
            //{
            //    foreach (AporteSocio aporte in AporteSocio)
            //    {
            //        aporte.IngresoDeProductoID = ingresoDeProducto.IngresoDeProductoID;
            //        db.AportesSocio.Add(aporte);
            //        db.SaveChanges();
            //    }
                
            //    return RedirectToAction("DistribuirProductos", new {@id= ingresoDeProducto.IngresoDeProductoID });
            //}
            return RedirectToAction("Index");
        }

        public ActionResult DistribuirProductos(int? id)
        {
            //IngresoDeProducto ingresoDeProducto = db.IngresoDeProductos.Find(id);
            //foreach (AporteSocio aporte in ingresoDeProducto.AportesSocio)
            //{
            //    float porcentaje = aporte.Monto / ingresoDeProducto.getCostoTotal();
            //    foreach (ProductoEsperado prodEsperado in ingresoDeProducto.ProductosEsperados)
            //    {
            //        foreach (ProductoDeSocio prodSocio in prodEsperado.ProductosDeSocio)
            //        {
            //            if (prodSocio.SocioID == aporte.SocioID)
            //            {
            //                prodSocio.CantidadEsperada = int.Parse((prodEsperado.CantidadEsperada * porcentaje).ToString());
            //                db.Entry(prodSocio).State = EntityState.Modified;
            //                db.SaveChanges();
            //            }
            //        }
            //    }

            //}

            //TERMINAR ESTE METODO QUE PERMITE DISTRIBUIR LOS PRODUCTOS...........................................................

            return RedirectToAction("Index");
        }

        // GET: /IngresoDeProducto/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            IngresoDeProducto importacion = db.IngresoDeProductos.Find(id);
            if (importacion == null)
            {
                return HttpNotFound();
            }
            return View(importacion);
        }

        // POST: /IngresoDeProducto/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "IngresoProductoID,Nombre,,Descripcion,Fecha")] IngresoDeProducto importacion)
        {
            if (ModelState.IsValid)
            {
                db.Entry(importacion).State = EntityState.Modified;
                db.SaveChanges();
                TempData["Correcto"] = "La importacion fue modificada correctamente!";
                return RedirectToAction("Index");
            }
            return View(importacion);
        }

        // GET: /IngresoDeProducto/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            IngresoDeProducto importacion = db.IngresoDeProductos.Find(id);
            if (importacion == null)
            {
                return HttpNotFound();
            }
            if (importacion.sePuedeEliminar())
            {
                TempData["Informacion"] = "Atencion! Va a eliminar la importacion...";
                return View(importacion);
            }
            else 
            {
                TempData["Informacion"] = "La importacion no puede ser eliminada por que tiene transacciones pendientes.";
                return RedirectToAction("Index");
            }

        }

        // POST: /IngresoDeProducto/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            IngresoDeProducto importacion = db.IngresoDeProductos.Find(id);
            if (importacion.GastosDeImportacion.Count == 0 && importacion.ProductosEsperados.Count == 0)
            {
                db.IngresoDeProductos.Remove(importacion);
                db.SaveChanges();
            }
            else
            {
                importacion.Eliminado = true;
                db.Entry(importacion).State = EntityState.Modified;
                //foreach (ProductoImportado p in importacion.ProductoImportados.ToList())
                //{
                //    db.ProductoImportadoes.Remove(p);
                //}
                db.SaveChanges();
                //db.Importacions.Remove(importacion);
                //db.SaveChanges();
            }
            TempData["Correcto"] = "La importacion fue eliminada.";
            return RedirectToAction("Index");
        }

        public ActionResult VerRecepcionar(int? id)
        {
            IngresoDeProducto ingresoDeProducto = db.IngresoDeProductos.Find(id);
            if (ingresoDeProducto.GastosDeImportacion.Count() == 0)
            {
                TempData["Informacion"] = "Aun no se registraron los Gastos de la Importacion!!! Si continua ya no podrá agregalos después!!";
            }
            //TempData[];

            return View(ingresoDeProducto);
        }

        // GET: /IngresoDeProducto/Details/5
        //[HttpPost, ActionName("Recepcionar")]
        //[ValidateAntiForgeryToken]
        public ActionResult Recepcionar(ICollection<ProductoEsperado> ProductoEsperado, ICollection<ProductoDeSocio> ProductoDeSocio, string IngresoDeProductoID)
        {

            foreach (ProductoDeSocio prodDeSocio in ProductoDeSocio)
            {
                ProductoDeSocio aux = db.ProductosDeSocio.Find(prodDeSocio.ProductoDeSocioID);
                aux.CantidadIngresada = prodDeSocio.CantidadIngresada;
                aux.CantidadActual = aux.CantidadActual + prodDeSocio.CantidadIngresada;
                db.Entry(aux).State = EntityState.Modified;
            }
            db.SaveChanges();

            int idIngreso = int.Parse(IngresoDeProductoID);
            IngresoDeProducto ingresoProd = db.IngresoDeProductos.Find(idIngreso);
            ingresoProd.FechaRecibida = DateTime.Now.Date;
            ingresoProd.CostoTotal = ingresoProd.getCostoTotal();

            foreach (ProductoEsperado prod in ProductoEsperado)
            {
                ProductoEsperado aux = db.ProductosEsperados.Find(prod.ProductoEsperadoID);
                aux.CantidadRecibida = prod.CantidadRecibida;
                db.Entry(aux).State = EntityState.Modified;
                Producto p = db.Productoes.Find(aux.ProductoID);
                p.Stock = p.Stock + aux.CantidadRecibida;
                if (p.Precio == 0)
                {
                    p.Precio = aux.PrecioUnitarioDeCompra + aux.PrecioUnitarioDeCompra * ingresoProd.porcentajeDeGastosDeImportacion();
                }
                else
                {
                    p.Precio = (p.Precio + (aux.PrecioUnitarioDeCompra+aux.PrecioUnitarioDeCompra * ingresoProd.porcentajeDeGastosDeImportacion())) / 2;
                }
                db.Entry(p).State = EntityState.Modified;
            }
            db.SaveChanges();
           
            TempData["Correcto"] = "Se confirmó el ingreso de los productos. El stock de los almacenes fue actualizado.";
            return RedirectToAction("Index");
            

        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
